#include "RingDisconnect.h"

#include <stdlib.h>
#include <sstream>
#include <stdio.h>

#include <Poco/DOM/Document.h>
#include <Poco/DOM/NodeIterator.h>
#include "misc/Interface.h"
#include "misc/Debug.h"
#include "nameserver/NameServer.h"
/*********************************************************/
void RingDisconnect::execute()
{
	Interface& iface = Interface::Instance();
	NameServer& ns = NameServer::Instance();
	ns.mutex.lock();
	bool found = false;
	for ( unsigned int i=0; i<ns.rings.size(); i++ ) {
		if ( ns.rings[i].getName() == ringName ) {
			ns.rings[i].removeClient(addr.toString());
			found = true;
		}
	}
	
	// Remove all keepalive & ack records of the node
	ns.remove(addr.toString());

	// Add the nodes address to the recently disconnected map
	ns.disconnected[addr.toString()] = Poco::Timestamp();
	ns.mutex.unlock();

	if ( !found ) {
		iface << "Cannot disconnect client from ring if client didn't register!" << std::endl;
		iface.flush();
	} else {
		iface << "Client: " << addr.toString() << " disconnected from ring: " << ringName << std::endl;
		iface.flush();
	}

	// Send an ack
	ack();
}
/*********************************************************/
std::string RingDisconnect::serialize() const
{
	NameServer& ns = NameServer::Instance();
	std::ostringstream		ostr;
	id = ns.getID();

	ostr << "<GS id='" << id << "'>";
	ostr << "<RingDisconnect>" << ringName << "</RingDisconnect>";
	ostr << "</GS>";

	return( ostr.str() );
}
/*********************************************************/
void RingDisconnect::deserialize(Poco::XML::NodeIterator& it)
{
	Poco::XML::Node* pNode = it.previousNode();
	ringName = pNode->innerText();
}
/*********************************************************/
void RingDisconnect::setName(const std::string& n)
{
	ringName = n;
}
/*********************************************************/
std::string RingDisconnect::getName() const
{
	return ringName;
}
/*********************************************************/
